package model

import (
	"fmt"
	"server/share"
	"server/share/config"
	"time"

	"github.com/hwcer/cosgo/times"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/yyds/errors"
)

const RoleTableOrder = 100

// RoleFieldTable ROLE 字段名和数字ID映射
//var RoleFieldTable = map[int32]string{}

func init() {
	Register(&Role{})
}

func NewRole() *Role {
	r := &Role{}
	r.Lv = 1
	r.Hook = &RoleHook{Time: times.Now().Unix()}
	for _, h := range Handle {
		if i, ok := h.(roleInit); ok {
			i.Init(r)
		}
	}
	return r
}

type TaskWeek struct {
	Id   int32   `json:"id" bson:"id"`
	Task []int32 `json:"task" bson:"task"`
}

func (this *TaskWeek) Clone(t time.Time) *TaskWeek {
	if this == nil {
		return &TaskWeek{}
	}
	ts := times.New(t)
	s, _ := ts.Sign(0)
	if this.Id != s {
		return &TaskWeek{}
	}
	r := *this
	r.Task = make([]int32, len(this.Task))
	copy(r.Task, this.Task)
	return &r
}

type Role struct {
	share.Player `bson:"inline"`
	Like         int64           `json:"like,omitempty" bson:"like"`   //点赞
	Viper        map[int32]int64 `json:"viper,omitempty" bson:"viper"` //VIP 月卡 周卡  ，
	Goods        map[int32]int64 `json:"goods,omitempty" bson:"goods"` //普通道具
	Ban          int32           `json:"-" bson:"ban"`                 //禁用
	//Record   map[int32]int64 `json:"record,omitempty" bson:"record"`                //成就记录
	Exp      int64     `json:"exp,omitempty" bson:"exp"`                      //经验
	Guid     string    `json:"guid,omitempty" bson:"guid" index:""`           //账号ID
	Create   int64     `json:"create,omitempty" bson:"create" `               //创建时间
	Update   int64     `json:"update,omitempty" bson:"update" `               //最后更新时间
	Install  int8      `json:"-" bson:"install"`                              //初始化
	Invite   uint64    `json:"invite,omitempty" bson:"invite" index:"SPARSE"` //邀请人
	Disciple int32     `json:"disciple,omitempty" bson:"disciple"`            //我累计邀请的人数
	TaskWeek *TaskWeek `json:"taskWeek,omitempty" bson:"taskWeek"`            //走任务
	//BuildingsInfo BuildingsInfoMgr `json:"buildingsInfo,omitempty" bson:"buildingsInfo"`  //建筑等级等等 {"500101":{"level":0, "beginTime": }, "等等"}
	SyncedUnit      SyncedUnitMgr   `json:"syncedUnit,omitempty" bson:"syncedUnit"`           //设置同步器 todo
	Talent          map[int32]int32 `json:"talent,omitempty" bson:"talent"`                   //天赋加点 Group --> Talent id
	UseTalentBranch []int32         `json:"useTalentBranch,omitempty" bson:"useTalentBranch"` //装备天赋树分支  []Group

	//Battle         string       `json:"battle" bson:"battle"`
	IconFrame      int32        `json:"iconFrame,omitempty" bson:"iconFrame"`
	BusinessCardID int32        `json:"businessCardID,omitempty" bson:"businessCardID"`
	BattleArea     string       `json:"battleArea,omitempty" bson:"battleArea"`
	RestArea       string       `json:"restArea,omitempty" bson:"restArea"`         //休息区
	IncubateList   IncubateList `json:"incubateList,omitempty" bson:"incubateList"` //蛋池,孵蛋

	Gs          int32           `json:"gs,omitempty" bson:"gs"`                   //新手引导步骤
	NoviceGuide map[int32]int32 `json:"noviceGuide,omitempty" bson:"noviceGuide"` // //新手引导分组 {'引导分组Id': 排序ID}

	Draw         DrawList        `json:"draw,omitempty" bson:"draw"`                 //抽卡记录
	DrawPool     map[int32]int32 `json:"drawPool,omitempty" bson:"drawPool"`         //卡池抽卡累计次数 {'卡池ID': '累计抽卡次数'}
	TotalDrawNum int32           `json:"totalDrawNum,omitempty" bson:"totalDrawNum"` // 累计抽卡次数

	BattlePoint int32 `json:"battlePoint,omitempty" bson:"battlePoint"` //通关关卡数量 ,,,战区最高关卡
	//Onhook      int64           `json:"onhook,omitempty" bson:"onhook"`           //最后挂机领取时间 MS
	LockItem map[string]int8 `json:"lockItem,omitempty" bson:"lockItem"` //物品锁  ??? TODO

	Hook *RoleHook `json:"hook,omitempty" bson:"hook"`

	//Team RoleTeam `json:"team,omitempty" bson:"team"`
	//TeamList         RoleTeamList   `json:"teamList,omitempty" bson:"teamList"`
	//TeamTalentBranch map[string]any `json:"teamTalentBranch,omitempty" bson:"teamTalentBranch"`

	FWbossX   int32           `json:"fWbossX,omitempty" bson:"FWbossX"`     //好友boss的保底怪物数量
	FWbossID  int32           `json:"fWbossID,omitempty" bson:"FWbossID"`   //自己发现的好友bossID
	HangPoint int32           `json:"hangPoint,omitempty" bson:"hangPoint"` //挂机收益点数
	NewStage  map[int32]int32 `json:"NewStage,omitempty" bson:"NewStage"`   //主线通过情况  原stage使用资源名当KEY  废弃
	HelpUnit  RoleHelpMgr     `json:"helpUnit,omitempty" bson:"helpUnit"`   //助阵列表

	StarSkill RoleStarSkill `json:"starSkill,omitempty" bson:"starSkill"` //星光体技能数据
	Star      *RoleStar     `json:"star,omitempty" bson:"star"`
	StarBuff  *RoleStarBuff `json:"starBuff,omitempty" bson:"starBuff"`

	Arena   *RoleArena `json:"arena,omitempty" bson:"Arena"`
	Defense int32      `json:"defense" bson:"Defense"` //竞技场防守阵容

	LReward int32       `json:"lReward,omitempty" bson:"lReward"` //等级奖励
	AppUnit RoleAppUnit `json:"appUnit,omitempty" bson:"appUnit"`
	//setlist,不知道都是什么玩意
	AchievementBall []int32 `json:"achievementBall,omitempty" bson:"achievementBall"` //成就球 原类型[]string
	Reputation      []int32 `json:"reputation,omitempty" bson:"reputation"`           //星光体绰号
	AstralImage     []int32 `json:"astralImage,omitempty" bson:"astralImage"`         //星光体形象
	Package         int32   `json:"package,omitempty" bson:"package"`                 //成就包装袋
	SpaceUnit       int32   `json:"spaceUnit,omitempty" bson:"spaceUnit"`             //个人空间助理
	SpaceProgress   []int32 `json:"spaceProgress,omitempty" bson:"spaceProgress" `
}

func (r *Role) Get(k string) (v any, ok bool) {
	switch k {
	case "Uid", "uid", "_id":
		return r.Uid, true
	case "Lv", "lv":
		return r.Lv, true
	case "Exp", "exp":
		return r.Exp, true
	case "Guid", "guid":
		return r.Guid, true
	case "Name", "name":
		return r.Name, true
	case "Icon", "icon":
		return r.Icon, true
	//case "Goods", "goods":
	//	return r.Goods, true
	//case "Record", "record":
	//	return r.Record, true
	case "Create", "create":
		return r.Create, true
	case "Update", "update":
		return r.Update, true
	default:
		return r.getFromHandle(k)
	}
}

func (r *Role) Set(k string, v any) (any, bool) {
	switch k {
	case "Uid", "uid", "_id":
		panic("uid write not allowed")
	case "Lv", "lv":
		r.Lv = dataset.ParseInt32(v)
	case "Exp", "exp":
		r.Exp = dataset.ParseInt64(v)
	case "Guid", "guid":
		r.Guid = v.(string)
	case "Name", "name":
		r.Name = v.(string)
	case "Icon", "icon":
		r.Icon = dataset.ParseInt32(v)
	//case "Goods", "goods":
	//	r.Goods = v.(map[int32]int64)
	//case "Record", "record":
	//	r.Record = v.(map[int32]int64)
	case "Create", "create":
		r.Create = v.(int64)
	case "Update", "update":
		r.Update = v.(int64)
	default:
		return r.setFromHandle(k, v)
	}
	return v, true
}

func (r *Role) Loading() updater.RAMType {
	return updater.RAMTypeAlways
}

func (r *Role) TableName() string {
	return "role"
}
func (r *Role) TableOrder() int32 {
	return RoleTableOrder
}

func (r *Role) New(u *updater.Updater) any {
	return NewRole()
}
func (r *Role) IType(iid int32) int32 {
	return config.ITypeRole
}
func (r *Role) Reset(u *updater.Updater, data *dataset.Document) error {
	return nil
}
func (r *Role) Field(u *updater.Updater, iid int32) (string, error) {
	if c, ok := config.Data.Role[iid]; ok {
		return c.Key, nil
	}
	return "", fmt.Errorf("unknown field id:%v", iid)
}

func (r *Role) Getter(u *updater.Updater, data *dataset.Document, keys []string) error {
	tx := db
	if len(keys) > 0 {
		tx = tx.Select(keys...)
	}
	uid := u.Uid()
	if uid == "" {
		return errors.New("Role.Getter uid not found")
	}
	v := NewRole()
	if tx = tx.Find(v, uid); tx.Error != nil {
		return tx.Error
	} else if tx.RowsAffected == 0 {
		return errors.ErrRoleNotExist
	}
	data.Reset(v)
	return nil
}
func (r *Role) Setter(u *updater.Updater, data dataset.Update) error {
	uid := u.Uid()
	if uid == "" {
		return errors.New("Role.Setter uid not found")
	}
	tx := db.Model(r).Update(map[string]any(data), uid)
	return tx.Error
}
